﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace RpaDesigner.Frame
{
    public class RubberBandAdorner : Adorner
    {
        private Point? _startPoint;
        private Point? _endPoint;
        private readonly Pen _rubberBandPen;
        private readonly DesignerCanvas _canvas;

        public RubberBandAdorner(DesignerCanvas canvas, Point? dragStartPoint) : base(canvas)
        {
            this._canvas = canvas;
            this._startPoint = dragStartPoint;
            this._rubberBandPen = new Pen(Brushes.LightSlateGray, 1)
            {
                DashStyle = new DashStyle(new double[] {2}, 1)
            };
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                if (!this.IsMouseCaptured)
                    this.CaptureMouse();

                this._endPoint = e.GetPosition(this);
                UpdateSelection();
                this.InvalidateVisual();
            }
            else
            {
                if (this.IsMouseCaptured) this.ReleaseMouseCapture();
            }

            e.Handled = true;
        }

        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            if (this.IsMouseCaptured) this.ReleaseMouseCapture();

            var adornerLayer = AdornerLayer.GetAdornerLayer(this._canvas);
            adornerLayer?.Remove(this);

            e.Handled = true;
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(RenderSize));
            if (this._startPoint.HasValue && this._endPoint.HasValue)
                drawingContext.DrawRectangle(Brushes.Transparent, this._rubberBandPen,
                    new Rect(this._startPoint.Value, this._endPoint.Value));
        }

        private void UpdateSelection()
        {
            this._canvas.SelectionService.ClearSelection();

            if (!this._startPoint.HasValue || !this._endPoint.HasValue) return;
            
            var rubberBand = new Rect(this._startPoint.Value, this._endPoint.Value);
            foreach (Control item in this._canvas.Children)
            {
                var itemRect = VisualTreeHelper.GetDescendantBounds(item);
                var itemBounds = item.TransformToAncestor(this._canvas).TransformBounds(itemRect);

                if (rubberBand.Contains(itemBounds))
                {
                    switch (item)
                    {
                        case Connection connection:
                            this._canvas.SelectionService.AddToSelection(connection);
                            break;
                        case DesignerItem di when di.ParentId == Guid.Empty:
                            this._canvas.SelectionService.AddToSelection(di);
                            break;
                    }
                }
            }
        }
    }
}